home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 101-125 / scopedisk106 / bbs-index / src / checkfiles.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  9.4 KB  |  257 lines

  1. /*
  2.  * CHECKFILES.C
  3.  *
  4.  * This module contains routines to read in the disk directory, search
  5.  * the file database for each filename found to see if it matches, etc.
  6.  *
  7.  */
  8.  
  9. #ifndef LATTICE_50
  10. #include "system.h"
  11. #endif
  12. #include "bbsindex.h"
  13.  
  14. /*
  15.  *             addunknown()
  16.  *             ------------
  17.  *             Adds a new entry to the list of unknown files found. If necessary,
  18.  *             more memory will be allocated to hold the new entry.
  19.  */
  20. int addunknown(name, size, date, dirnum)
  21. char *name;
  22. long size;
  23. int date, dirnum;
  24. {
  25.        static DIRENTRY *dirbase, *dir;
  26.  
  27.        if (numdirentries >= MAXDIRENT) {
  28.                scripterror("directory table full. Skipping rest of files\n");
  29.                return (FALSE);
  30.        }
  31.        if ((numdirentries % DIRFRAG) == 0)     /* Allocate new block */
  32.                dirbase = mymalloc(DIRENTRYSIZE * DIRFRAG);
  33.  
  34.        dir = &dirbase[numdirentries % DIRFRAG];
  35.  
  36.        strcpy(dir->name, name);
  37.        dir->size       = size;
  38.        dir->date       = date;
  39.        dir->dirnum     = dirnum;
  40.  
  41.        direntries[numdirentries++] = dir;
  42.        return (TRUE);
  43. }
  44.  
  45. /*
  46.  *             find()
  47.  *             ------
  48.  *             Does a binary search of the file records looking for the specified
  49.  *             filename. Returns pointer to the file record if found, NULL if not
  50.  *             found.
  51.  */
  52. UDHEAD *find(name)
  53. char *name;
  54. {
  55.        long low = 0, high = numrecs -1;
  56.        long mid;
  57.        int cmp;
  58.  
  59.        while (high >= low) {
  60.                mid = (low + high) / 2;
  61.                cmp = stricmp(ptrblock[mid]->disk_name, name);
  62.                if (!cmp && ptrblock[mid]->type == 0)           /* Found match */
  63.                        return (ptrblock[mid]);
  64.                if (cmp > 0)                                            /* Too far ahead, go backwards */
  65.                        high = mid-1;
  66.                else                                                            /* Too far below, go forwards */
  67.                        low  = mid+1;
  68.        }
  69.        return (NULL);
  70. }
  71.  
  72. /*
  73.  *             scandir()
  74.  *             ---------
  75.  *             Scans directory, adding the files found either to the 'unknown'
  76.  *             list or updating the pointers in the main file database appropriately.
  77.  */
  78. int scandir(dirname, dirnum)
  79. char *dirname;
  80. int dirnum;
  81. {
  82.        UDHEAD *f;
  83.        struct tm *filedate;
  84.        int bbspcdate;
  85.  
  86.        dirlock = Lock(dirname, ACCESS_READ);
  87.        if (dirlock == NULL) {
  88.                scripterror("can't find directory ");
  89.                print2(dirname, ", skipping\n");
  90.                return (TRUE);
  91.        }
  92.  
  93.        if (!Examine(dirlock, fib)) {
  94.                scripterror("can't examine directory ");
  95.                print2(dirname, ", skipping\n");
  96.                UnLock(dirlock);
  97.                dirlock = NULL;
  98.                return (TRUE);
  99.        }
  100.  
  101.        while (ExNext(dirlock, fib)) {
  102.                chkabort();
  103.                if (fib->fib_DirEntryType > 0)  /* Skip over directories */
  104.                        continue;
  105.                if (f = find(fib->fib_FileName)) {
  106.                        f->online = 1;
  107.                        f->valid = (fib->fib_Size == f->length);
  108.                        f->dirnum = dirnum;
  109.                } else {
  110.                        /*
  111.                         *              Convert AmigaDOS date (# days since 1/1/78, # mins
  112.                         *              since midnight) into ANSI date (# seconds since 1/1/70)
  113.                         *              then convert that into BBS-PC! format.
  114.                         */
  115.                        long ansidate;
  116.                        ansidate = (fib->fib_Date.ds_Days + (365 * 8) + 2) * 86400;
  117.                        filedate = gmtime(&ansidate);
  118.                        bbspcdate = (((filedate->tm_year * 13) +
  119.                                                  (filedate->tm_mon+1)) * 32) +
  120.                                                   filedate->tm_mday;
  121.                        if (!addunknown(fib->fib_FileName, fib->fib_Size, bbspcdate,
  122.                                                                                                                                        dirnum)) {
  123.                                UnLock(dirlock);
  124.                                dirlock = NULL;
  125.                                return (FALSE);
  126.                        }
  127.  
  128.                }
  129.        }
  130.        if (IoErr() != ERROR_NO_MORE_ENTRIES) {
  131.                scripterror("error reading directory ");
  132.                print2(dirname, ", skipping\n");
  133.        }
  134.        UnLock(dirlock);
  135.        dirlock = NULL;
  136.        return (TRUE);
  137. }
  138.  
  139. /*
  140.  *             diskcmp()
  141.  *             ---------
  142.  *             Compares the disk filenames of two file headers, and returns true
  143.  *             if they are equal. Used by the sort routine in check_files().
  144.  */
  145. int diskcmp(f1,f2)
  146. UDHEAD **f1, **f2;
  147. {
  148.        return (stricmp((*f1)->disk_name, (*f2)->disk_name));
  149. }
  150.  
  151. /*
  152.  *             com_checkfiles()
  153.  *             ----------------
  154.  *             This command scans the file directories specified on the command
  155.  *             line (or if none, then using those specified in the CFGINFO.DAT
  156.  *             file). Each file in the catalogue is searched for in the file
  157.  *             catalogue, and those that are found are marked as "Online"; if
  158.  *             the disk filesize matches the catalogue filesize, then their
  159.  *             "valid" flag is also set. Files which are not found are stored
  160.  *             in a seperate array, which can be printed with the FOREIGN command.
  161.  *             After this, any other files listed in the IGNORE list are also marked
  162.  *             as valid.
  163.  *
  164.  *             Note that before the scan, the files are sorted into alphabetical
  165.  *             order, by diskname, to allow a binary search to be done. Afterwards,
  166.  *             if this disrupted a previous sorting order, they are sorted back
  167.  *             to their original state.
  168.  */
  169. void com_checkfiles()
  170. {
  171.        int dirnum;
  172.        IGNORE *ig;
  173.        UDHEAD *f;
  174.  
  175.        if (checkfiles)
  176.                return;
  177.  
  178.        CHECKDATABASE();
  179.        qsort(ptrblock, numrecs, sizeof(UDHEAD *), diskcmp);
  180.        if (compos >= comlen) {
  181.                readconfigfile();
  182.                for (dirnum = 0; dirnum < NUM_SECT && dirnames[dirnum][0]; dirnum++) {
  183.                        chkabort();
  184.                        if (!scandir(dirnames[dirnum], dirnum))
  185.                                break;
  186.                }
  187.        } else {
  188.                for (dirnum = 0; dirnum < NUM_SECT; dirnum++) {
  189.                        if (compos >= comlen)
  190.                                break;
  191.                        strcpy(dirnames[dirnum], getstring());
  192.                        chkabort();
  193.                        if (!scandir(dirnames[dirnum], dirnum))
  194.                                break;
  195.                }
  196.        }
  197.        /*
  198.         *              Now mark any "ignored" files as valid.
  199.         */
  200.        for (ig = firstignore; ig; ig = ig->next) {
  201.                if (f = find(ig->name))
  202.                        f->valid = 1;
  203.        }
  204.        chkabort();
  205.        if (sorted)
  206.                qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
  207.        checkfiles = TRUE;
  208. }
  209.  
  210. /*
  211.  *             com_foreign()
  212.  *             -------------
  213.  *             This command prints out the list of foreign files, i.e. files
  214.  *             not in the catalogue, using the format string setup with
  215.  *             FORMAT. Not all fields are valid.
  216.  */
  217. void com_foreign()
  218. {
  219.        /*
  220.         *              Standard file header template for foreign files.
  221.         *              Note file[] is an array, so we can say file->x instead of file.x
  222.         */
  223.        static UDHEAD file[1] = {{
  224.                0,                                              /* Record type (== valid)                               */
  225.                1, 1, 1, 1,                     /* Local, Binary, Valid and Online :-)  */
  226.                0,                                              /* Directory number is set later                */
  227.                "",                                             /* Catalogue filename, filled in later  */
  228.                0,                                              /* Date is set later                                    */
  229.                0, 0, 0,                                /* Section 0, Directory 0, no accesses  */
  230.                0,                                              /* Length is set later                                  */
  231.                "",                                             /* Disk name is set later                               */
  232.                "AmigaDos",                             /* The file owner                                               */
  233.                "Directory = ",                 /* File comment, set later                              */
  234.        }};
  235.  
  236.        int i;
  237.  
  238.        if (!checkfiles) {
  239.                scripterror("can't do FOREIGN before CHECKFILES\n");
  240.                Cleanup(10);
  241.        }
  242.  
  243.        for (i = 0; i < numdirentries; i++) {
  244.                chkabort();
  245.                /* Setup actual file parameters for format() */
  246.                strcpy(file->disk_name, direntries[i]->name);
  247.                strncpy(file->cat_name, direntries[i]->name, CAT_LEN);
  248.                strncpy(file->desc+12, dirnames[direntries[i]->dirnum], DESC_LEN-12);
  249.                file->desc[DESC_LEN] = CHAR_NULL;
  250.                file->length    = direntries[i]->size;
  251.                file->date              = direntries[i]->date;
  252.                file->dirnum    = direntries[i]->dirnum;
  253.                format(out, MAXOUT, formatstring, file, checkfiles);
  254.                putstring(out);
  255.        }
  256. }
  257.